import logging
import datetime
from neo4jDBOP import neo4jDBOP
import json

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

logfile = "logs/log_for_nonexistentClass_%s.txt" % datetime.date.today().strftime('%y%m%d')
fh = logging.FileHandler(logfile, mode='a')
fh.setLevel(logging.INFO)

ch = logging.StreamHandler()
ch.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

logger.addHandler(fh)
logger.addHandler(ch)

neo4j_conf = {
    "uri" : "neo4j://211.71.15.39:7685",
    "user" : "neo4j",
    "password" : "pysr"
}
# browser : 211.71.15.39:7472
# 211.71.15.39:7471

neo4j_conf_readonly = {
    "uri" : "neo4j://211.71.15.39:9687",
    "user" : "neo4j",
    "password" : "python"
}
# browser : 211.71.15.39:9474
# 211.71.15.39:9473

DBOP = neo4jDBOP(neo4j_conf=neo4j_conf)

class InheritGraph(object):
    def __init__(self):
        # self.pkg_name = pkg_name
        # self.version = version
        self.base_dict = {} # {python file: {子类: [父类]}}
        self.import_dict = {} # {python file: {fully_qualified_name:[name, asname, path]}}

    def dict_update(self, base_dict, import_dict):
        self.base_dict.update(base_dict)
        self.import_dict.update(import_dict)

    def generate_inherit_graph(self):
        base_file = "base_dict.json"
        import_file = "import_dict.json"
        with open(base_file, "w+") as f:
            f.write(json.dumps(self.base_dict))
        with open(import_file, "w+") as f:
            f.write(json.dumps(self.import_dict))
        
        for pyfile in self.base_dict:
            # print()
            # print("*******************************************************")
            # print("pyfile: ", pyfile)
            for child_class in self.base_dict[pyfile]:
                child_fully_qualified_name = pyfile + "." + child_class
                # print("child_fully_qualified_name: ", child_fully_qualified_name)
                for father_class in self.base_dict[pyfile][child_class]:
                    # print("father_class: ", father_class)
                    father_path = father_class.split('.')
                    import_name = pyfile + "." + father_path[0]
                    # print("import_name: ", import_name)
                    if father_class in self.base_dict[pyfile]:
                        father_fully_qualified_name = pyfile + "." + father_class
                    elif pyfile in self.import_dict and import_name in self.import_dict[pyfile]:
                        import_info = self.import_dict[pyfile][import_name]
                        # print("import_info: ", import_info)
                        father_fully_qualified_name = ""
                        if import_info[2] is not None:
                            father_fully_qualified_name += import_info[2] + "."
                        if import_info[1] is None:
                            father_fully_qualified_name += import_info[0]
                        else:
                            father_fully_qualified_name += import_info[1]
                        for i in range(1, len(father_path)):
                            father_fully_qualified_name += "." + father_path[i]
                    else:
                        logger.info("%s is not exist, inherited by %s.", father_class, child_fully_qualified_name)
                        continue
                    # print("father_fully_qualified_name: ", father_fully_qualified_name)
                    DBOP.insertInheritRelation(father=father_fully_qualified_name, child=child_fully_qualified_name)
                    fun_list = DBOP.searchFunction(fully_qualified_name=father_fully_qualified_name)
                    for fun_name in fun_list:
                        child_function_name = child_fully_qualified_name + "." + fun_name[1]
                        print("child_function_name: ", child_function_name)
                        result = DBOP.searchAPI(fully_qualified_name=child_function_name)
                        print("result: ", result)
                        if len(result) == 0:
                            fun_info = DBOP.searchFunctionInfo(fully_qualified_name=fun_name[0])
                            DBOP.insertFunction(fully_qualified_name=child_function_name, striped_name=fun_name[1], args=fun_info[0])
                            DBOP.insertFunctionContains(father_fully_qualified_name=child_fully_qualified_name, function_fully_qualified_name=child_function_name)
                            DBOP.mappingInherit(father_name=fun_name[0], child_name=child_function_name)
